package com.niuxuliang.activity.controler;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.api.R;
import com.niuxuliang.activity.entity.WorkFlowEntity;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.*;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.*;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * 测试
 *
 * @author xl.niu
 */
@Slf4j
@RestController
@RequestMapping("/activity")
public class ActivityController {

    @Autowired
    private RepositoryService repositoryService;//管理流程定义
    @Autowired
    private TaskService taskService;//任务管理
    @Autowired
    private RuntimeService runtimeService;//执行管理，包括启动、推进、删除流程实例等操作
    @Autowired
    private HistoryService historyService;//历史管理(执行完的数据的管理)

    /**
     * 启动一个实例
     */
    @GetMapping("/startProcessInstance")
    public void startProcessInstance() {
        System.out.println("Number of process definitions : " + repositoryService.createProcessDefinitionQuery().count());
        System.out.println("Number of tasks : " + taskService.createTaskQuery().count());
        runtimeService.startProcessInstanceByKey("myProcess_1");
    }

    /**
     * 发起流程
     *
     * @return
     */
    @GetMapping("/startProcess")
    public R startProcess(WorkFlowEntity entity) {
        HashMap<String, Object> variables = new HashMap<>();
        variables.put("username", entity.getAssignee());
        variables.put("user", "xiaohua");

        ProcessInstance instance = runtimeService.startProcessInstanceByKey("myProcess_1", variables);

        //验证是否启动成功
        //通过查询正在运行的流程实例来判断
        ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();

        //根据流程实例ID来查询
        List<ProcessInstance> runningList = processInstanceQuery.processInstanceId(instance.getProcessInstanceId()).list();
        log.debug("====start process instance====" + runningList);

        String instanceId = instance.getId();//流程实例ID

        //设置处理人
        Task task = taskService.createTaskQuery().processInstanceId(instanceId).singleResult();
        if (task != null) {
            //自动完成第一步
            Map<String, Object> map = new HashMap<String, Object>(2);
            map.put("check", 1);
            map.put("personId", "zq0788");
            taskService.setAssignee(task.getId(), "0000");
            taskService.complete(task.getId(), map);

            task = taskService.createTaskQuery().processInstanceId(instanceId).singleResult();
            taskService.setAssignee(task.getId(), "zq0002");
        } else {
//            throw new BusinessException(WorkTaskErrorCode.WORK_TASK_START_PROCESS_ERROR);
        }

        HashMap<String, Object> res = new HashMap<>();
        res.put("流程实例ID", instance.getId());
        res.put("流程定义ID", instance.getProcessDefinitionId());

        return R.ok(res);
    }


    /**
     * 我的待办
     *
     * @return
     */
    @RequestMapping("/myWaitingToDo")
    @ResponseBody
    public R getActList(Integer page, Integer limit, String name) {

        List<org.activiti.engine.task.Task> taskList = taskService.createTaskQuery()
                .taskAssignee(name)
                .listPage(page - 1, limit);
        long count = taskService.createTaskQuery()
                .taskAssignee(name).count();

        List<Map<String, String>> list = new ArrayList<>();


        String username = "";
        if (taskList != null && taskList.size() != 0) {
            HistoricVariableInstance historicVariableInstance = historyService.createHistoricVariableInstanceQuery()
                    .variableName("username").taskId(taskList.get(0).getId()).singleResult();

            username = (String) historicVariableInstance.getValue();
        }

        for (Task t : taskList) {
            Map map2 = new HashMap();
            t.setDescription(username + "-审批单-" + t.getCreateTime());
            map2.put("description", username + "-审批单-" + t.getCreateTime());
            map2.put("name", t.getName());
            map2.put("executionId", t.getExecutionId());
            map2.put("status", t.getDelegationState());
            map2.put("id", t.getId());
            list.add(map2);
        }
//        jsonResponse.setData(list);
//        jsonResponse.setCount(count);
        return R.ok(list);
    }

    /**
     * 获取流程状态
     *
     * @param instanceId
     * @return
     */
    @RequestMapping("/getApply_status")
    public R getApplyStatus(String instanceId) {

        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(instanceId).singleResult();
        //获取bpmnModel对象
        BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());

        //因为我们这里只定义了一个Process 所以获取集合中的第一个即可
        Process process = bpmnModel.getProcesses().get(0);

        //获取所有的FlowElement信息
        Collection<FlowElement> flowElements = process.getFlowElements();

        Map<String, String> map = new HashMap<>();
        for (FlowElement flowElement : flowElements) {
            //判断是否是连线
            if (flowElement instanceof SequenceFlow) {
                SequenceFlow sequenceFlow = (SequenceFlow) flowElement;
                String ref = sequenceFlow.getSourceRef();
                String targetRef = sequenceFlow.getTargetRef();
                map.put(ref + targetRef, sequenceFlow.getId());
            }
        }

        //获取流程实例 历史节点(全部)
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId(instanceId).list();

        //各个历史节点   两两组合 key
        Set<String> keyList = new HashSet<>();
        for (HistoricActivityInstance i : list) {
            for (HistoricActivityInstance j : list) {
                if (i != j) {
                    keyList.add(i.getActivityId() + j.getActivityId());
                }
            }
        }

        //高亮连线ID
        Set<String> highLine = new HashSet<>();
        keyList.forEach(s -> highLine.add(map.get(s)));

        //获取流程实例 历史节点（已完成）
        List<HistoricActivityInstance> listFinished = historyService.createHistoricActivityInstanceQuery().processInstanceId(instanceId).finished().list();

        //高亮节点ID
        Set<String> highPoint = new HashSet<>();
        listFinished.forEach(s -> highPoint.add(s.getActivityId()));

        //获取流程实例 历史节点（待办节点）
        List<HistoricActivityInstance> listUnFinished = historyService.createHistoricActivityInstanceQuery().processInstanceId(instanceId).unfinished().list();

        //需要移除的高亮连线
        Set<String> set = new HashSet<>();

        //待办高亮节点
        Set<String> waitingToDo = new HashSet<>();
        listUnFinished.forEach(s -> {
            waitingToDo.add(s.getActivityId());

            for (FlowElement flowElement : flowElements) {
                //判断是否是 用户节点
                if (flowElement instanceof UserTask) {
                    UserTask userTask = (UserTask) flowElement;

                    if (userTask.getId().equals(s.getActivityId())) {
                        List<SequenceFlow> outgoingFlows = userTask.getOutgoingFlows();
                        //因为 高亮连线查询的是所有节点  两两组合 把待办 之后  往外发出的连线 也包含进去了  所以要把高亮待办节点 之后 即出的连线去掉
                        if (outgoingFlows != null && outgoingFlows.size() > 0) {
                            outgoingFlows.forEach(a -> {
                                if (a.getSourceRef().equals(s.getActivityId())) {
                                    set.add(a.getId());
                                }
                            });
                        }
                    }
                }
            }
        });

        highLine.removeAll(set);


        //获取当前用户
        Set<String> iDo = new HashSet<>(); //存放 高亮 我的办理节点
        //当前用户已完成的任务
        List<HistoricTaskInstance> taskInstanceList = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee("NIU")
                .finished()
                .processInstanceId(instanceId).list();

        taskInstanceList.forEach(a -> iDo.add(a.getTaskDefinitionKey()));

        Map<String, Object> reMap = new HashMap<>();
        reMap.put("highPoint", highPoint);
        reMap.put("highLine", highLine);
        reMap.put("waitingToDo", waitingToDo);
        reMap.put("iDo", iDo);

        return R.ok(reMap);
    }

    /**
     * 通过
     *
     * @param id
     * @param msg
     * @return
     */
    @RequestMapping("/approval_msg")
    public R approvalPass(String id, String msg) {

        if (StringUtils.isNotBlank(msg)) {
            String str = msg.replace("\"", "");
            taskService.setVariable(id, "msg", str);
        }
        taskService.complete(id);

        return R.ok("");
    }

}
